using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using HCore.Core;
using HCore.IOC.Beans.Factory;
using HCore.IOC.Beans.Factory.Attribute.Attr;
using HCore.Unity.Manager;
using HCore.Utility.Task;
using JetBrains.Annotations;
using UnityEngine;

namespace System
{
    [UsedImplicitly]
    [HCore.IOC.Context.Stereotype.Component]
    public class GameDataService : IInitializingBean
    {
        [Autowired] private GameDataManager aGameDataManager;
        private IDictionary<Type, object> mType2Data;

        public void AfterPropertiesSet()
        {
            var taskQueue = new TaskQueue(true);

            // 添加外部任务（游戏数据加载任务）
            // taskQueue.AddExternalTask();
            // aGameDataManager.AddAsyncLoadFinishAction(() => taskQueue.CompleteExternalTask());

            // 加载非Json数据
            // taskQueue.AddAsyncTask(LoadNotJasonData);

            // 加载精灵
            // taskQueue.AddCoroutineTask(LoadSprites);

            // 执行数据加载
            taskQueue.Execute(taskContext =>
            {
                Debug.Log($"[GameDataService][AfterPropertiesSet] process: {taskContext.TaskTotal}, complete: {taskContext.TaskCompletedCount}");
                // 进度相等，说明游戏数据加载完成
                if (taskContext.IsCompleted)
                {
                    isLoadFinishAction = true;
                    OnGameDataLoadCompleteEvent?.Invoke();
                }
            });
        }

        /// <summary>
        ///     加载非Json数据
        /// </summary>
        /// <returns></returns>
        private Task LoadNotJasonData()
        {
            mType2Data = new Dictionary<Type, object>();
            return Task.Run(() =>
            {
                // mType2Data.TryAdd(typeof(TowerGameData), new TowerGameData());
                // mType2Data.TryAdd(typeof(CellInfoGameData), new CellInfoGameData());
                // mType2Data.TryAdd(typeof(EnemyGameData), new EnemyGameData());
            });
        }

        /// <summary>
        ///     同步获取数据
        ///     <para>只能在异步加载完成后调用此函数</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetData<T>()
        {
            Assert.NotNull(mType2Data, "游戏数据还未初始化！");
            if (mType2Data.TryGetValue(typeof(T), out var value)) return (T)value;
            return aGameDataManager.GetData<T>();
        }

        /// <summary>
        ///     异步获取数据
        /// </summary>
        /// <param name="finishAction"></param>
        /// <typeparam name="T"></typeparam>
        public void GetDataAsync<T>(Action<T> finishAction)
        {
            aGameDataManager.GetDataAsync<T>(data =>
            {
                if (data != null) finishAction.Invoke(data);
                else if (isLoadFinishAction) finishAction.Invoke(GetData<T>());
                else AddGameDataLoadCompleteEvent(() => finishAction.Invoke(GetData<T>()));
            });
        }

        private IEnumerator LoadSprites(Action completeHandler)
        {
            yield return null;
            // SpriteUtils.LoadSprites();
            // completeHandler.Invoke();
        }

        /// <summary>
        ///     添加游戏数据加载完成事件
        ///     <para>如果已经加载完成，再调用这个方法，则直接执行传入的方法</para>
        /// </summary>
        /// <param name="event"></param>
        public void AddGameDataLoadCompleteEvent(Action @event)
        {
            Debug.Log("[GameDataService][AddGameDataLoadCompleteEvent]------------!");
            if (isLoadFinishAction)
            {
                @event.Invoke();
            }
            else
            {
                OnGameDataLoadCompleteEvent -= @event;
                OnGameDataLoadCompleteEvent += @event;
            }
        }

        #region 注册和触发事件：GameDataLoadCompleteEvent

        /// <summary>
        ///     游戏数据加载完成事件
        /// </summary>
        private event Action OnGameDataLoadCompleteEvent;

        /// <summary>
        ///     数据是否已经加载完成
        /// </summary>
        private bool isLoadFinishAction;

        #endregion
    }
}